﻿using System.Linq;
using ConfigurationSettings;
using FileSystemControls;
using FileSystemControls.ListViewItems;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Windows.Forms;
using ServiceLocator;

namespace CustomControls
{
    public partial class FileListView : UserControl
    {
        private readonly bool _designMode = (LicenseManager.UsageMode == LicenseUsageMode.Designtime);
        private int _oldPercentage;
        //private ApplicationSettings _configSettings;

        //public event EventHandler<SynchEventArgs> SynchPathEvent;
        public event EventHandler SynchPathEvent;

        public string CurrentPath
        {
            get { return fileSystemListView1.CurrentPath; }
        }

        public bool EnableFilter
        {
            set
            {
                if (value)
                {
                    flowLayoutPanelFilter.Height = 35;
                    flowLayoutPanelFilter.AutoSize = true;
                }
                else
                {
                    flowLayoutPanelFilter.AutoSize = false;
                    flowLayoutPanelFilter.Height = 1;
                }
            }
        }

        public List<FileSystemListViewItem> SelectedItems
        {
            get { return fileSystemListView1.SelectedItems; }
        }

        public IEnumerable<FileListViewItem> SelectedFileItems
        {
            get
            {
                return fileSystemListView1.SelectedFileItems;
            }
        }

        public IEnumerable<DirectoryListViewItem> SelectedDirectoryItems
        {
            get
            {
                return fileSystemListView1.SelectedDirectoryItems;
            }
        }

        //public List<FileSystemListViewItem> Items
        //{
        //    get
        //    {
        //        return fileSystemListView1.Items.Cast<FileSystemListViewItem>().ToList();
        //    }
        //}

        public IEnumerable<FileListViewItem> Files
        {
            get
            {
                return fileSystemListView1.Items.OfType<FileListViewItem>().ToList();
            }
        }

        public IEnumerable<DirectoryListViewItem> Directories
        {
            get
            {
                return fileSystemListView1.Items.OfType<DirectoryListViewItem>().ToList();
            }
        }

        /**********************************************************************************************************************************************/
        /**********************************************************************************************************************************************/
        public FileListView()
        {
            InitializeComponent();

            if (_designMode)
            {
                return;
            }

            flowLayoutPanelFilter.AutoSize = false;
            flowLayoutPanelFilter.Height = 1;

            fileSystemListView1.AddItemProgress += FileSystemListViewAddItemProgress;
            //fileSystemListView1.AddItemComplete += FileSystemListViewAddItemComplete;
            fileSystemListView1.PathChanged += FileSystemListViewPathChanged;

            LoadFavorites();
        }

        /// <summary> 
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        /// This was stolen from the generated code
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                //Need to remove the event handlers so we don't keep stuff around simply because of the event references.
                fileSystemListView1.AddItemProgress -= FileSystemListViewAddItemProgress;
                fileSystemListView1.PathChanged -= FileSystemListViewPathChanged;

                components.Dispose();
            }
            base.Dispose(disposing);
        }


        private void FileListView_Load(object argSender, EventArgs argEventArgs)
        {
            textBoxPath.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
        }

        /// <summary>
        /// Resets the controls when the path in the FSLV changes.
        /// </summary>
        /// <param name="argSender">FSLV object that raised the event.</param>
        /// <param name="argEventArgs">Event arguments that hold the new path.</param>
        private void FileSystemListViewPathChanged(object argSender, FileSystemPathChangedEventArgs argEventArgs)
        {
            try
            {
                //autoSizeTextBoxPath.Text = argEventArgs.NewPath;
                textBoxPath.Text = argEventArgs.NewPath;
                dropDownButtonFavorites.SetFavorite(argEventArgs.NewPath);

                //Set the "Free Space" if possible
                labelFreeSpace.Text = fileSystemListView1.AvailableFreeSpaceText;

                fileSystemListView1.Focus();

            }
            catch (Exception pathChangedEx)
            {
                MessageBox.Show(string.Format("Error in FileSystemListView_PathChanged - {0}", pathChangedEx.Message));
            }
        }

        public void SetPath(string argNewPath)
        {
            fileSystemListView1.SetPath(argNewPath);
        }

        public void SetConfiguration()
        {
            fileSystemListView1.SetConfiguration();
        }

        /// <summary>
        /// Scans the configuration object and adds favorites to the dropdown objects.
        /// </summary>
        public void LoadFavorites()
        {
            try
            {
                IApplicationSettings localSettings = Locator.Resolve<IApplicationSettings>();

                FillDriveBoxes();

                //Loop through Favorites
                foreach (KeyValuePair<string, string> favoriteEntry in localSettings.FavoriteList)
                {
                    string favoriteName = favoriteEntry.Key;
                    string favoritePath = favoriteEntry.Value;

                    ToolStripMenuItem menuItemFavoriteLeft = new ToolStripMenuItem(favoriteName, null, FavoriteClick);
                    ToolStripMenuItem menuItemFavoriteRight = new ToolStripMenuItem(favoriteName, null, FavoriteClick);

                    menuItemFavoriteLeft.Tag = favoritePath;
                    menuItemFavoriteRight.Tag = favoritePath;

                    // HTP dropDownButtonLeft.AddMenuItem(MenuItemFavoriteLeft);
                    dropDownButtonFavorites.AddMenuItem(menuItemFavoriteRight);
                }

                //autoSizeTextBoxPath.ResizeTextBox();
            }

            catch (Exception loadEx)
            {
                MessageBox.Show(string.Format("Error in LoadFavorites: {0}", loadEx.Message));
            }
        }

        /// <summary>
        /// Looks for which item was clicked and sets the current directory to that favorite.
        /// </summary>
        /// <param name="argSender">The ToolStripDropDownItem object that raised this event.</param>
        /// <param name="argEvtArgs">The event arguments object. Unused.</param>
        private void FavoriteClick(object argSender, EventArgs argEvtArgs)
        {
            try
            {
                ToolStripDropDownItem clickedItem = (ToolStripDropDownItem)argSender;

                fileSystemListView1.SetPath((string)clickedItem.Tag);
            }

            catch (Exception favoriteEx)
            {
                MessageBox.Show(string.Format("Error in Favorite_Click{0}", favoriteEx.Message));
            }
        }

        /// <summary>
        /// Scans the system for drives and fills the dropdown objects with the results.
        /// </summary>
        private void FillDriveBoxes()
        {
            try
            {
                dropDownButtonFavorites.ClearItems();

                // Get a list of the drives in this computer.
                DriveInfo[] allDrives = DriveInfo.GetDrives();

                foreach (DriveInfo currentDrive in allDrives)
                {
                    string driveLabel;
                    if (currentDrive.IsReady)
                    {
                        driveLabel = currentDrive.Name + " - " + currentDrive.VolumeLabel;
                    }
                    else
                    {
                        driveLabel = currentDrive.Name + " - Not Ready";
                    }

                    ToolStripMenuItem leftFavorite = new ToolStripMenuItem(driveLabel, null, FavoriteClick);
                    ToolStripMenuItem rightFavorite = new ToolStripMenuItem(driveLabel, null, FavoriteClick);

                    leftFavorite.Tag = currentDrive.Name;
                    rightFavorite.Tag = currentDrive.Name;

                    dropDownButtonFavorites.AddMenuItem(rightFavorite);
                }

                dropDownButtonFavorites.AddSeparator();
            }
            catch (Exception fillDriveEx)
            {
                MessageBox.Show(string.Format("Error in FillDriveBoxes: {0}", fillDriveEx.Message));
            }
        }

        ///// <summary>
        ///// Initializes the FileSystemListViews to their default directories.
        ///// </summary>
        //private void LoadDefaultDirectories()
        //{
        //    string LeftDefaultFolder;
        //    string RightDefaultFolder;

        //    try
        //    {
        //        //Load Left pane default directories
        //        if (_configSettings.LeftDefaultFolderType == FolderType.FavoriteFolder)
        //        {
        //            LeftDefaultFolder = _configSettings.FavoriteList.ContainsKey(_configSettings.LeftDefaultFolder) ? _configSettings.FavoriteList[_configSettings.LeftDefaultFolder] : new DriveInfo(Application.ExecutablePath).RootDirectory.FullName;
        //        }
        //        else
        //        {
        //            LeftDefaultFolder = _configSettings.LeftDefaultFolder;
        //        }

        //        // HTP fileSystemListViewLeft.DefaultPath = LeftDefaultFolder;

        //        //Load Right pane default directories
        //        if (_configSettings.RightDefaultFolderType == FolderType.FavoriteFolder)
        //        {
        //            RightDefaultFolder = _configSettings.FavoriteList.ContainsKey(_configSettings.RightDefaultFolder) ? _configSettings.FavoriteList[_configSettings.RightDefaultFolder] : new DriveInfo(Application.ExecutablePath).RootDirectory.FullName;
        //        }
        //        else
        //        {
        //            RightDefaultFolder = _configSettings.RightDefaultFolder;
        //        }

        //        fileSystemListViewRight.DefaultPath = RightDefaultFolder;

        //    }

        //    catch (Exception LoadDefaultEx)
        //    {
        //        MessageBox.Show(string.Format("Error in LoadDefaultDirectories{0}", LoadDefaultEx.Message));
        //    }
        //}

        /// <summary>
        /// Event handler for tracking the progress of adding FileItems to the Left-hand list view.
        /// </summary>
        /// <param name="argSender">Not Used</param>
        /// <param name="argEvtArgs">Not Used</param>
        private void FileSystemListViewAddItemProgress(object argSender, AddItemProgressEventArgs argEvtArgs)
        {
            //TODO: ?This causes an OutOfMemory Exception when there are more than 3,500 entries in the dir
            if (argEvtArgs.CurrentPercentage != _oldPercentage)
            {
                _oldPercentage = argEvtArgs.CurrentPercentage;
                labelItemPercentage.Text = string.Format("{0}%", argEvtArgs.CurrentPercentage.ToString());
                labelItemPercentage.Refresh();
            }
        }

        //TODO:Bind the labelFreeSpace to fileSystemListView1.AvailableFreeSpaceText
        //private void FileSystemListViewAddItemComplete(object argSender, AddItemCompleteEventArgs argEventArgs)
        //{
        //    labelFreeSpace.Text = argEventArgs.AvailableFreeSpace.ToString();
        //}

        private void buttonSynchPath_Click(object argSender, EventArgs argEvtArgs)
        {
            //SynchPathEvent.Raise(this, new SynchEventArgs(fileSystemListView1.CurrentPath));
            SynchPathEvent.Raise(this, null);
        }

        //private void autoSizeTextBoxPath_KeyDown(object argSender, KeyEventArgs argEventArgs)
        //{
        //    switch (argEventArgs.KeyCode)
        //    {
        //        case Keys.Enter:
        //            NavigatePath((AutoSizeTextBox)argSender);
        //            argEventArgs.Handled = true;
        //            break;
        //        default:
        //            argEventArgs.Handled = false;
        //            break;
        //    }
        //}
        private void textBoxPath_KeyDown(object argSender, KeyEventArgs argEventArgs)
        {
            switch (argEventArgs.KeyCode)
            {
                case Keys.Enter:
                    NavigatePath((TextBox)argSender);
                    argEventArgs.Handled = true;
                    break;
                default:
                    argEventArgs.Handled = false;
                    break;
            }

        }

        /// <summary>
        /// Occurs when the user hits "Enter" in the AutoSizeTextBox.
        /// </summary>
        /// <param name="argSender">The AutoSizeTextBox that fired the event.</param>
        private void NavigatePath(TextBox argSender)
        {
            try
            {
                ////Get the ComboBox that sent the message
                if (argSender.Text == "")
                    return;

                argSender.Text = argSender.Text.Trim();

                fileSystemListView1.SetPath(argSender.Text);
            }
            catch (Exception navigatePathEx)
            {
                fileSystemListView1.Cursor = Cursors.Default;
                MessageBox.Show(string.Format("Error in NavigatePath: {0}", navigatePathEx.Message));
            }
        }

        //public void LoadOpenWith(ApplicationSettings argConfigSettings)
        public void LoadOpenWith()
        {
            //fileSystemListView1.LoadOpenWith(argConfigSettings);
            fileSystemListView1.LoadOpenWith();
        }

        public void RefreshPath()
        {
            fileSystemListView1.RefreshPath();
        }

        private void buttonFilter_Click(object argSender, EventArgs argEventArgs)
        {

            //If the comboBox doesn't have the typed filter in it...
            if (!comboBoxNameFilter.Items.Contains(comboBoxNameFilter.Text))
            {
                //Add the text as a new filter choice
                comboBoxNameFilter.Items.Add(comboBoxNameFilter.Text);
            }

            //Set the filters and refresh the FSLV
            fileSystemListView1.NameFilter = comboBoxNameFilter.Text;
            fileSystemListView1.ExtFilter = comboBoxExtFilter.Text;
            fileSystemListView1.RefreshPath();

        }

        private void buttonFilterReset_Click(object argSender, EventArgs argEventArgs)
        {
            comboBoxNameFilter.Text = @"*";
            comboBoxExtFilter.Text = @"*";
            fileSystemListView1.NameFilter = @"*";
            fileSystemListView1.ExtFilter = @"*";
            fileSystemListView1.RefreshPath();
        }

        public void RenameItems()
        {
            fileSystemListView1.RenameItems();
        }

    }

    //public class SynchEventArgs : EventArgs
    //{
    //    private string Path { get; set; }

    //    public SynchEventArgs(string argPath)
    //    {
    //        Path = argPath;
    //    }
    //}
}
